#ifndef __PID_H__
#define __PID_H__

#include "main.h"
#include "basicmath.h"

/**
 * @brief 	pid类
 */
#ifdef __cplusplus
class pid_t
{
public:
    enum PID_ENUM{
        LLAST	= 0,
        LAST 	= 1,
        NOW 	= 2,
        POSITION_PID = 4,            //位置式pid
        DELTA_PID = 5,               //增量式pid
        D_FIRST_EN = 6,              //微分先行
        D_FIRST_DISEN = 7,           //不微分先行
        FINISH = 8,                  //到达稳态
        UNFINISH = 9,                //未到达稳态
        DEADBAND_CLEAR_I = 10,       //死区积分清零
        DEADBAND_NOT_CLEAR_I = 11    //死区积分不清零
    };
    float p = 0.0f;	//p
    float i = 0.0f;	//i
    float d = 0.0f;	//d
    float f = 0.0f;	//f	前馈系数

    float set[3] = {0.0f,0.0f,0.0f};		//目标值,包含NOW， LAST， LLAST上上次
    float get[3] = {0.0f,0.0f,0.0f};		//测量值
    float err[3] = {0.0f,0.0f,0.0f};		//误差

    float integral = 0.0f;				    //积分项

    float pout = 0.0f;						//p输出
    float iout = 0.0f;						//i输出
    float dout = 0.0f;						//d输出

    float pos_out = 0.0f;					//本次位置式输出
    float last_pos_out = 0.0f;				//上次输出
    float delta_u = 0.0f;					//本次增量值
    float delta_out = 0.0f;				    //本次增量式输出 = last_delta_out + delta_u
    float last_delta_out = 0.0f;			//上次增量式输出

#if 0
    float max_err; 					//最大处理误差（暂不使用）
#endif


    PID_ENUM pid_mode = POSITION_PID;				            //pid模式
    PID_ENUM d_first_mode = D_FIRST_DISEN;			            //微分先行模式
    PID_ENUM deaband_integral_clear_mode = DEADBAND_CLEAR_I;   //进入死区时是否清零积分项


    float deadband = 0.0f;					//死区值
    float MaxOutput = 0.0f;				//输出限幅
    float IntegralLimit = 0.0f;			//积分限幅
    //初始化pid参数
    void pid_param_init(
            PID_ENUM 	mode,
            PID_ENUM 	d_first_mode,
            PID_ENUM    deadzone_i_clear_mode,
            float   	maxout,
            float 	    intergral_limit,
            float	    deadband,
            float 	    kp,
            float 	    ki,
            float 	    kd,
            float       kf
    );
    //pid计算函数
    float pid_calc(float get_v, float target_v);
    float chassis_pid_calc(float get_v, float target_v);
    //稳态判断
    PID_ENUM steady_check();
    //中途改变参数
    // void set_k(float val);
    // void set_i(float val);
    // void set_d(float val);
    // void set_f(float val);
    // void set_deadband(float deadband);
    // void set_MaxOutput(uint32_t MaxOutput);
    // void set_IntegralLimit(uint32_t IntegralLimit);
    // //改变设置
    // void set_mode(uint32_t mode);
    // void set_d_first_mode(PID_ENUM mode);
    pid_t(){};
    ~pid_t(){};
};
#endif

#endif

